from gibe.plugin import Plugin
from gibesitemap.model import SitemapCache

from turbogears import controllers, expose, identity, widgets, validators, error_handler, validate, paginate
import routes

from gibe.plugin import add_plugin_data, plugins
from gibe.util import utcnow, utc
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from gibe import model

def add_utc_timezone(d):
    return d.replace(tzinfo=utc)

class SitemapController(controllers.Controller):

    @expose(template="genshi:gibesitemap.templates.sitemap", format="xml")
    @add_plugin_data(template="genshi:gibesitemap.templates.sitemap")
    def sitemap(self, blog, action, sitemap):
        context = {}
        sitemap_urls = []
        for k, v in plugins.items():
            contribute_sitemap = getattr(v, "contribute_sitemap", None)
            if contribute_sitemap:
                contribute_sitemap(blog, sitemap, sitemap_urls, context)
        return dict(urls = sitemap_urls)

    @expose(template="genshi:gibesitemap.templates.index", format="xml")
    @add_plugin_data(template="genshi:gibesitemap.templates.index")
    def index(self, blog, action):
        context = {}
        sitemaps = []
        for k, v in plugins.items():
            contribute_sitemaps = getattr(v, "contribute_sitemaps", None)
            if contribute_sitemaps:
                contribute_sitemaps(blog, sitemaps, context)

        return dict(sitemaps=sitemaps)

class Sitemap(object):
    def __init__(self, name, lastmod = None):
        self.name = name
        self.lastmod = lastmod

    @property
    def loc(self):
        return routes.url_for('gibesitemap.sitemap', sitemap=self.name, qualified = True)

class SitemapUrl(object):
    def __init__(self, loc, lastmod = None, changefreq = None, priority = None):
        self.loc = loc
        self.lastmod = lastmod
        self.changefreq = changefreq
        self.priority = priority


class GibeSitemapPlugin(Plugin):
    """
    This plugin adds a basic sitemap system to Gibe.
    """

    def initialise(self):
        if not SitemapCache.table.exists():
            SitemapCache.table.create()
        return True

    def contribute_sitemaps(self, blog, sitemaps, context):
        sitemaps.append(Sitemap("gibesitemap_posts"))
        sitemaps.append(Sitemap("gibesitemap_archives"))
        sitemaps.append(Sitemap("gibesitemap_frontpage"))
        sitemaps.append(Sitemap("gibesitemap_tags"))

    def contribute_sitemap(self, blog, sitemap_name, sitemap_entries, context):
        sitemap_name = sitemap_name.replace('.', '_')
        contribute_specific_sitemap = getattr(self, '_contribute_sitemap_%s' % (sitemap_name,), None)
        if contribute_specific_sitemap:
            contribute_specific_sitemap(blog, sitemap_entries, context)

    def _contribute_sitemap_gibesitemap_posts(self, blog, sitemap_entries, context):
        post_count = 0
        now = utcnow()
        for post in model.Post.select(model.Post.c.published == True, order_by=model.desc(model.Post.c.modification_time)):
            modification_time = add_utc_timezone(post.modification_time)
            if modification_time + timedelta(days=3) > now:
                changefreq = "hourly"
            elif modification_time + timedelta(days=15) > now:
                changefreq = "daily"
            elif modification_time + timedelta(days=45) > now:
                changefreq = "weekly"
            elif modification_time + timedelta(days=90) > now:
                changefreq = "monthly"
            else:
                changefreq = "monthly"

            if modification_time + timedelta(days=15) > now:
                priority = 0.9
            elif modification_time + timedelta(days=30) > now:
                priority = 0.8
            elif modification_time + timedelta(days=90) > now:
                priority = 0.7
            elif modification_time + timedelta(days=180) > now:
                priority = 0.6
            elif modification_time + timedelta(days=360) > now:
                priority = 0.5
            elif modification_time + timedelta(days=720) > now:
                priority = 0.4
            else:
                priority = 0.3

            sitemap_entries.append(SitemapUrl(routes.url_for('posts', post=post, qualified=True), lastmod = modification_time, changefreq = changefreq, priority=priority))


    def _contribute_sitemap_gibesitemap_frontpage(self, blog, sitemap_entries, context):

        post_lastmod_select = model.select([model.Post.c.modification_time], model.Post.c.post_id > 0, order_by=[model.desc(model.Post.c.modification_time)])
        r = post_lastmod_select.execute()
        lastmod = list(r)[0][0]
        lastmod = add_utc_timezone(lastmod)

        sitemap_entries.append(SitemapUrl(routes.url_for('frontpage', qualified=True), lastmod = lastmod, changefreq = "hourly", priority = 1.0))

    def _contribute_sitemap_gibesitemap_archives(self, blog, sitemap_entries, context):

        post_lastmod_select = model.select([model.Post.c.modification_time], model.Post.c.post_id > 0, order_by=[model.desc(model.Post.c.modification_time)])
        r = post_lastmod_select.execute()
        lastmod = list(r)[0][0]
        lastmod = add_utc_timezone(lastmod)

        sitemap_entries.append(SitemapUrl(routes.url_for('archives', qualified=True), lastmod = lastmod, changefreq = "daily", priority = 0.1))

        now = utcnow()

        for year, how_many in blog.years():
            if year == now.year:
                sitemap_entries.append(SitemapUrl(routes.url_for('archives_year', year=year, qualified = True), lastmod = lastmod, changefreq = "daily", priority = 0.1))
            else:
                archive_lastmod = datetime(year=year+1, month=1, day=1, hour = 0, minute = 0, tzinfo = utc)
                sitemap_entries.append(SitemapUrl(routes.url_for('archives_year', year=year, qualified = True), lastmod = archive_lastmod, changefreq = "never", priority = 0.1))

            for year, month, dt, how_many in blog.months(year):
                if year == now.year and month == now.month:
                    sitemap_entries.append(SitemapUrl(routes.url_for('archives_month', year=year, month=month, qualified = True), lastmod = lastmod, changefreq = "daily", priority = 0.1))
                else:
                    archive_lastmod = datetime(year=year, month=month, day=1, hour = 0, minute = 0, tzinfo = utc) + relativedelta(months=1)
                    sitemap_entries.append(SitemapUrl(routes.url_for('archives_month', year=year, month=month, qualified = True), lastmod = archive_lastmod, changefreq = "never", priority = 0.1))

    def _contribute_sitemap_gibesitemap_tags(self, blog, sitemap_entries, context):
        tags = blog.all_tags_count()
        s = model.select([model.Tag.c.name, model.func.max(model.Post.c.modification_time)], model.Tag.join_to('posts'), group_by=[model.post_tag.c.tag_id])
        r = s.execute()

        for tag, lastmod in r:
            lastmod = add_utc_timezone(lastmod)
            sitemap_entries.append(SitemapUrl(routes.url_for('tags', tagname=tag, qualified = True), lastmod = lastmod, changefreq = "daily", priority = 0.1))

    def map_routes(self, blog, maps, controllers):
        controllers['gibesitemap.SitemapController'] = SitemapController()

        maps.append(('gibesitemap.sitemap_index', 'sitemap.xml', dict(controller='gibesitemap.SitemapController', action='index')))
        maps.append(('gibesitemap.sitemap', 'sitemap_:(sitemap).xml', dict(controller='gibesitemap.SitemapController', action='sitemap')))

        print "Hello!\n" * 6

        return
